#include "format.h"
#include "charset.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int file_format(u_int8_t *bytes,int length)
{
	if(length<2) return FORMAT_INCOMPLETE;
	if(bytes[0]!=bytes[1]) return FORMAT_INVALID;
	return bytes[0];
}

int file_size(u_int8_t *bytes,int length)
{
	if(length<6) return SIZE_INCOMPLETE; // incomplete file
	int size1=bytes[2]|(bytes[3]<<8);
	int size2=bytes[4]|(bytes[5]<<8);
	if(size1!=size2) return SIZE_INVALID;
	return size1+10;
}

int is_file_complete(u_int8_t *bytes,int length)
{
	int size=file_size(bytes,length);
	if(size<0) return 0;
	if(length>=size) return 1;
	else return 0;
}

int is_checksum_correct(u_int8_t *bytes,int length)
{
	int size=file_size(bytes,length);
	if(size<0) return 0;
	if(length<size) return 0;

	u_int32_t sum=0;
	for(int i=6;i<size-4;i++) sum+=bytes[i];

	u_int32_t check=bytes[size-4]|(bytes[size-3]<<8)|(bytes[size-2]<<16)|(bytes[size-1]<<24);

	return check==sum;
}

void fix_checksum(u_int8_t *bytes,int length)
{
	int size=file_size(bytes,length);
	if(size<0) return;
	if(length<size) return;

	u_int32_t sum=0;
	for(int i=6;i<size-4;i++) sum+=bytes[i];

	bytes[size-4]=sum&0xff;
	bytes[size-3]=(sum>>8)&0xff;
	bytes[size-2]=(sum>>16)&0xff;
	bytes[size-1]=(sum>>24)&0xff;
}

int analyze_file(u_int8_t *bytes,int length)
{
	int format=file_format(bytes,length);
	if(format==FORMAT_INCOMPLETE) return FILE_INCOMPLETE;
	if(format==FORMAT_INVALID) return FILE_FORMAT_INVALID;

	int size=file_size(bytes,length);
	if(size==SIZE_INCOMPLETE) return FILE_INCOMPLETE;
	if(size==SIZE_INVALID) return FILE_SIZE_INVALID;
	if(size==0) return FILE_EMPTY;
	if(length<size) return FILE_INCOMPLETE;

	if(!is_checksum_correct(bytes,length)) return FILE_CHECKSUM_INVALID;

	return FILE_OK;
}

char *level_name(u_int8_t *bytes,int length)
{
	static char namebuf[16*3+1];

	if(length<38) return NULL;

	namebuf[0]=0;
	for(int i=0;i<16;i++)
	{
		char *c=charset_table[bytes[i+22]];
		if(!c) break;
		strcat(namebuf,c);
	}

	return namebuf;
}



